`include "common.svh"
import "DPI-C" function longint mem_read(
  longint addr,
  byte size
);
import "DPI-C" function void mem_write(
  longint addr,
  byte size,
  longint data
);
module mem (
    input          clk,
    input          rst,
    //Memory Req Port
    input          req_valid,
    input  MEM_REQ req,
    output         req_ready,
    input          req_kill_prev,
    //Load early wakeup
    output         early_wakeup_valid,
    output PRF_IDX early_wakeup_prf_idx,
    //Memory Rsp Port
    output         rsp_valid,
    output MEM_RSP rsp,
    input          rsp_ready
);
  logic s1_rsp_valid, s1_rsp_ready;
  MEM_RSP s1_rsp;
  /* verilator lint_off UNUSEDSIGNAL */
  MEM_REQ s1_req;
  /* verilator lint_on UNUSEDSIGNAL */
  wire s1_rsp_fire = s1_rsp_valid & s1_rsp_ready;
  decouple inst_decouple_s1 (
      .i_valid(req_valid),
      .i_ready(req_ready),
      .o_valid(s1_rsp_valid),
      .o_ready(s1_rsp_ready | req_kill_prev),
      .*
  );
  decouple inst_decouple_rsp (
      .i_valid(s1_rsp_valid),
      .i_ready(s1_rsp_ready),
      .o_valid(rsp_valid),
      .o_ready(rsp_ready),
      .rst(rst | req_kill_prev),
      .*
  );
  wire req_fire = req_valid & req_ready;
  always_ff @(posedge clk) begin
    if (req_fire) begin
      s1_rsp.rob_idx <= req.rob_idx;
      s1_rsp.prf_idx <= req.prf_idx;
      s1_rsp.has_data <= 'b0;
      s1_rsp.has_rd <= req.has_rd;
      s1_rsp.data <= 'b0;
      if (req.cmd == MEM_READ) begin
        s1_rsp.data <= mem_read(req.addr, {4'b0, req.size});
        s1_rsp.has_data <= 'b1;
      end else if (req.cmd == MEM_WRITE) begin
        mem_write(req.addr, {4'b0, req.size}, req.data);
      end
      s1_req <= req;
    end
    if (s1_rsp_fire) begin
      rsp <= s1_rsp;
      if (s1_req.cmd == MEM_READ) begin
        if (s1_req.sign) begin
          case (s1_req.size)
            4'b0001: rsp.data[63:8] <= {56{s1_rsp.data[7]}};
            4'b0010: rsp.data[63:16] <= {48{s1_rsp.data[15]}};
            4'b0100: rsp.data[63:32] <= {32{s1_rsp.data[31]}};
            default: ;
          endcase
        end
      end
    end
  end
  assign early_wakeup_valid   = s1_rsp_valid & s1_rsp_ready & ~req_kill_prev & (s1_req.cmd == MEM_READ);
  assign early_wakeup_prf_idx = s1_req.prf_idx;

endmodule
